package com.miras.client;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.Base64Utils;

import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;

import javax.annotation.PostConstruct;
import java.util.concurrent.TimeUnit;

/**
 * @author Gjing
 **/
@Component
public class NettyClient {
    private Logger log = LoggerFactory.getLogger(getClass());
    static String encoded = "wrE6gWOf0oIIIr0OO2DDjA==";
    private EventLoopGroup group = new NioEventLoopGroup();
    @Value("${netty.port}")
    private int port;
    @Value("${netty.host}")
    private String host;
    private SocketChannel socketChannel;

    @PostConstruct
    public void start() {
//        EventLoopGroup group = new NioEventLoopGroup();
        Bootstrap bootstrap = new Bootstrap()
                .group(group)
                //该参数的作用就是禁止使用Nagle算法，使用于小数据即时传输
                .option(ChannelOption.TCP_NODELAY, true)
                .channel(NioSocketChannel.class)
                .handler(new NettyClientInitializer());

        try {
            ChannelFuture future = bootstrap.connect(host, port).sync();
            log.info("客户端成功....");
            //客户端断线重连逻辑
            log.info("port========================"+port);
            future.addListener((ChannelFutureListener) future1 -> {
                if (future1.isSuccess()) {
                    log.info("连接Netty服务端成功");
                } else {
                    log.info("连接失败，进行断线重连");
                    future1.channel().eventLoop().schedule(() -> start(), 20, TimeUnit.SECONDS);
                }
            });
//            Key key = createKey(encoded);
//            byte[] bt = jdkAES("我是测试数据",key);
            //发送消息
            //
            future.channel().writeAndFlush("123131123sssdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddssssssssssssssssssssssssssssssssssssssssssssssssssssss123131123sssdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddssssssssssssssssssssssssssssssssssssssssssssssssssssss123131123sssdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddsssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss12132sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss12132sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss12132#");

            // 等待连接被关闭
            future.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            group.shutdownGracefully();
        }
    }
    public static Key createKey(String encoded) {
        try {
            // key转换,根据字节数组生成AES密钥
            byte[] sessionKey = Base64Utils.decodeFromString(encoded);
            SecretKeySpec key = new SecretKeySpec(sessionKey, "AES");
            return key;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    public static byte[] jdkAES(String context, Key key) {
        try {

            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");

            cipher.init(Cipher.ENCRYPT_MODE, key);
            //将加密并编码后的内容解码成字节数组
            byte[] result = cipher.doFinal(context.getBytes());

//			System.out.println("jdk aes:" + Base64.encode(result));

            return result;

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}
